package com.iotechn.unimall.admin.api.equipment;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dobbinsoft.fw.core.exception.AdminServiceException;
import com.iotechn.unimall.data.domain.ComputerRoomDO;
import com.iotechn.unimall.data.domain.InspectionDO;
import com.iotechn.unimall.data.enums.EquipmentStatusType;
import com.iotechn.unimall.data.exception.ExceptionDefinition;
import com.dobbinsoft.fw.core.exception.ServiceException;
import com.dobbinsoft.fw.support.model.Page;
import com.iotechn.unimall.data.domain.EquipmentDO;
import com.iotechn.unimall.data.mapper.ComputerRoomMapper;
import com.iotechn.unimall.data.mapper.EquipmentMapper;
import com.iotechn.unimall.data.mapper.InspectionMapper;
import com.iotechn.unimall.data.util.QRCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


/**
 * Generate Code By Unimall
 */
@Service
public class equipmentServiceImpl implements equipmentService {

    @Autowired
    private EquipmentMapper equipmentMapper;
    @Autowired
    private ComputerRoomMapper computerRoomMapper;
    @Autowired
    private InspectionMapper inspectionMapper;
    @Autowired
    private QRCodeUtil qrCodeUtil;

    @Override
    public boolean delete(Long id, Long adminId) throws ServiceException {
        //查询设备信息
        EquipmentDO equipmentDO = equipmentMapper.selectById(id);
        //更改机房设备数量
        ComputerRoomDO computerRoomDO = computerRoomMapper.selectById(equipmentDO.getRoomId());
        int i = computerRoomDO.getNumber();
        computerRoomDO.setNumber(i - 1);
        computerRoomMapper.updateById(computerRoomDO);
        return equipmentMapper.deleteById(id) > 0;
    }

    @Override
    public Page<EquipmentDO> list(String searchKeyWord, String type, String room, Integer page, Integer limit, Long adminId) throws ServiceException {
        QueryWrapper<EquipmentDO> wrapper = new QueryWrapper<EquipmentDO>();
        if (searchKeyWord != null) {
            wrapper.like("id", searchKeyWord)
                    .or().like("equipment_type", searchKeyWord)
                    .or().like("equipment_no", searchKeyWord);
        }
        if (type != null) {
            wrapper.eq("status", type);
        }
        if (room != null) {
            wrapper.eq("room_name", room);
        }
        return equipmentMapper.selectPage(Page.div(page, limit, EquipmentDO.class), wrapper.orderByDesc("id"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public EquipmentDO create(String equipmentType, String equipmentNo, String roomName, Long roomId, String inspectionItems, Long adminId) throws ServiceException {
        Date now = new Date();
        EquipmentDO insertDO = new EquipmentDO();
        insertDO.setEquipmentType(equipmentType);
        List<EquipmentDO> equipmentDOS = equipmentMapper.selectList(new QueryWrapper<EquipmentDO>().eq("room_id",roomId).eq("equipment_type",equipmentType));
        if (!CollectionUtils.isEmpty(equipmentDOS)){
            for (int i=0; i<equipmentDOS.size(); i++){
                if (equipmentNo.equals(equipmentDOS.get(i).getEquipmentNo())){
                    throw new AdminServiceException(ExceptionDefinition.EQUIPMENTNO_REPEAT);
                }
            }
        }
        insertDO.setEquipmentNo(equipmentNo);
        insertDO.setRoomName(roomName);
        insertDO.setRoomId(roomId);
        insertDO.setInspectionItems(inspectionItems);
        insertDO.setStatus(EquipmentStatusType.normal.getCode());
        insertDO.setGmtUpdate(now);
        insertDO.setGmtCreate(now);
        //更改机房设备数量
        ComputerRoomDO computerRoomDO = computerRoomMapper.selectById(roomId);
        int i = computerRoomDO.getNumber();
        computerRoomDO.setNumber(i + 1);
        computerRoomMapper.updateById(computerRoomDO);
        if (equipmentMapper.insert(insertDO) > 0) {
            EquipmentDO equipmentDO = equipmentMapper.selectById(insertDO.getId());
            equipmentDO.setCode(qrCodeUtil.generateQRCodeImage(String.valueOf(insertDO.getId()),800,800,"id",String.valueOf(insertDO.getId())));
            equipmentMapper.updateById(equipmentDO);
            return insertDO;
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String edit(Long id, String equipmentType, String equipmentNo, String roomName, Long roomId, String inspectionItems, Long adminId) throws ServiceException {
        Date now = new Date();
        EquipmentDO updateDO = new EquipmentDO();
        updateDO.setId(id);
        updateDO.setEquipmentType(equipmentType);
        List<EquipmentDO> equipmentDOS = equipmentMapper.selectList(new QueryWrapper<EquipmentDO>().eq("room_id",roomId).eq("equipment_type",equipmentType));
        if (!CollectionUtils.isEmpty(equipmentDOS)){
            for (int i=0; i<equipmentDOS.size(); i++){
                if (equipmentNo.equals(equipmentDOS.get(i).getEquipmentNo())){
                    throw new AdminServiceException(ExceptionDefinition.EQUIPMENTNO_REPEAT);
                }
            }
        }
        updateDO.setEquipmentNo(equipmentNo);
        updateDO.setRoomName(roomName);
        updateDO.setRoomId(roomId);
        updateDO.setInspectionItems(inspectionItems);
        updateDO.setGmtUpdate(now);
        if (equipmentMapper.updateById(updateDO) > 0) {
            return "ok";
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String discard(Long id, String flag, Long adminId) throws ServiceException {
        Date now = new Date();
        EquipmentDO equipmentDO = equipmentMapper.selectById(id);
        if ("1".equals(flag)) {
            //启用
            equipmentDO.setStatus(EquipmentStatusType.normal.getCode());
        } else {
            //弃用
            equipmentDO.setStatus(EquipmentStatusType.discard.getCode());
        }
        equipmentDO.setGmtUpdate(now);
        if (equipmentMapper.updateById(equipmentDO) > 0) {
            return "ok";
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    public List<EquipmentDO> xiaList(String roomName, String equipmentType, Long adminId) throws ServiceException {
        if (equipmentType == null) {
            List<EquipmentDO> equipmentDOS = equipmentMapper.selectList(new QueryWrapper<EquipmentDO>().eq("room_name", roomName));
            equipmentDOS = equipmentDOS.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new
                    TreeSet<>(Comparator.comparing(EquipmentDO :: getEquipmentType))), ArrayList::new));
            return equipmentDOS;
        } else {
            List<EquipmentDO> equipmentDOS = equipmentMapper.selectList(new QueryWrapper<EquipmentDO>().eq("room_name", roomName)
                    .eq("equipment_type", equipmentType));
            return equipmentDOS;
        }
    }


    @Override
    public EquipmentDO chart(String roomId, Long adminId) throws ServiceException {
        EquipmentDO equipmentDO = new EquipmentDO();
        //根据机房id查询该机房所有设备
        List<EquipmentDO> equipmentDOS = equipmentMapper.selectList(new QueryWrapper<EquipmentDO>().eq("room_id", roomId).groupBy("equipment_type"));
        if (!CollectionUtils.isEmpty(equipmentDOS)) {
            equipmentDO.setEquipmentTypeList(equipmentDOS);
            for (EquipmentDO equipmentDO1 : equipmentDOS) {
                //根据机房id和设备类型查询所有设备编号
                List<EquipmentDO> equipmentDOS1 = equipmentMapper.selectList(new QueryWrapper<EquipmentDO>().eq("room_id", roomId)
                        .eq("equipment_type", equipmentDO1.getEquipmentType()));
                if (!CollectionUtils.isEmpty(equipmentDOS1)) {
                    equipmentDO1.setEquipmentNoList(equipmentDOS1);
                    for (EquipmentDO equipmentDO2 : equipmentDOS1) {
                        //根据设备id查询巡检记录
                        List<InspectionDO> inspectionDOList = inspectionMapper.selectList(new QueryWrapper<InspectionDO>()
                                .eq("equipment_id", equipmentDO2.getId()).orderByDesc("gmt_create"));
                        if (!CollectionUtils.isEmpty(inspectionDOList)){
                            if (inspectionDOList.size()>=2){
                                equipmentDO2.setInspectionDOList(inspectionDOList.subList(0,2));
                            }else {
                                equipmentDO2.setInspectionDOList(inspectionDOList);
                            }
                        }
                    }
                }
            }
        }
        return equipmentDO;
    }


    @Override
    public String createCode(String id, Long adminId) throws ServiceException {
        return qrCodeUtil.generateQRCodeImage(id,800,800,"id",id);
    }

}
